use crate::byte_cursor::ByteCursor;

pub trait XRType {
    fn serialize(&self) -> Result<Vec<u8>, crate::error::Error>;
    #[allow(unused)]
    fn deserialize(data:&mut ByteCursor) -> Result<Self, crate::error::Error> where Self: Sized;
}

pub enum Types {
    None = 0x00,
    Bool = 0x01,
    Int = 0x02,
    Float = 0x03,
    String = 0x04,
    Array = 0x05,
    Object = 0x06,
    Refence = 0x07,
}

impl Types {
    pub fn from_u8(value:u8)->Option<Types> {
        match value {
            0x00 => Some(Self::None),
            0x01 => Some(Self::Bool),
            0x02 => Some(Self::Int),
            0x03 => Some(Self::Float),
            0x04 => Some(Self::String),
            0x05 => Some(Self::Array),
            0x06 => Some(Self::Object),
            0x07 => Some(Self::Refence),
            _ => {
                Option::None
            }
        }
    }
}

impl XRType for bool {
    fn serialize(&self) -> Result<Vec<u8>, crate::error::Error> {
        let b = if *self {1} else {0};
        Ok(vec![(Types::Bool as u8) | (b as u8) << 4])
    }

    fn deserialize(data:&mut ByteCursor) -> Result<Self, crate::error::Error> {
        if let Some(v) = data.read_one() {
            Ok((v & 0x0F) == 1)
        }
        else {
            Err("data length not enough".into())
        }
    }
}

#[inline]
fn serialize_int(data: i128)->Result<Vec<u8>, crate::error::Error>{
    if data >= 0 && data <= 0xF {
        Ok(vec![(Types::Int as u8) | ((data as u8) << 4)])
    }
    else {
        let mut result:Vec<u8> = Vec::new();
        let mut head = (Types::Int as u8) | 0x8;
        let abs_value = data.abs();
        let negative_mask = abs_value != data;
        let bitsize = 128 - abs_value.leading_zeros() + 1;//加1是因为要预留一个符号位
        let bytesize = bitsize.div_ceil(8) as u8;
        //i128最多占用16个字节，所以bytesize的最大值也就是16所以4个bit完全足够
        head |= bytesize << 4;
        result.push(head);
        for i in 0..bytesize - if negative_mask {1} else {0} {
            result.push((abs_value >> (i * 8)) as u8);
        }
        if negative_mask {
            let last_index = bitsize - 1;
            result.push(((abs_value >> (last_index * 8)) as u8) | 0x80);
        }
        Ok(result)
    }
}

#[inline]
fn deserialize_int(data:&mut ByteCursor)->Result<i128, crate::error::Error>{
    let head = data.read_one();
    if let Some(head) = head {
        let len = head >> 4;
        if (head & 0x8) == 0 {
            return Ok(len as i128);
        }
        let mut value:i128 = 0;
        for i in 0..(len - 1) {
            let next_v = data.read_one();
            if let Some(next_v) = next_v {
                value |= (next_v.to_owned() as i128) << (i * 8);
            } else {
                return Err("data not length enough".into());
            }
        }
        let last_v = data.read_one();
        if let Some(last_v) = last_v {
            let abs_v = last_v & 0x7f;
            value |= (abs_v << ((len - 1) * 8)) as i128;
            if abs_v != last_v {
                value = -value;
            }
        } else {
            return Err("data not length enough".into());
        }
        Ok(value)
    }
    else {
        Err("no header data".into())
    }
}

macro_rules! impl_int {
    ($t:ty) => {
        impl XRType for $t {
            fn serialize(&self) -> Result<Vec<u8>, crate::error::Error> {
                serialize_int(self.to_owned() as i128)
            }

            fn deserialize(data:&mut ByteCursor) -> Result<Self, crate::error::Error> {
                let result = deserialize_int(data);
                match result {
                    Ok(v) => Ok(v as Self),
                    Err(e) => Err(e),
                }
            }
        }
    };
}

impl_int!(i8);
impl_int!(i16);
impl_int!(i32);
impl_int!(i64);
impl_int!(i128);
impl_int!(u8);
impl_int!(u16);
impl_int!(u32);
impl_int!(u64);
impl_int!(u128);

enum FloatType {
    F32(f32),
    F64(f64),
}

#[inline]
fn deserialize_float(data:&mut ByteCursor)->Result<FloatType, crate::error::Error>{
    let head = data.read_one();
    if let Some(head) = head {
        if (head & 0x0F) != (Types::Float as u8) {
            return Err("data type not match".into());
        }
        let is_long = (head & 0x8) == 0x8;
        if is_long {
            let bytes = data.read(8);
            if let Some(bytes) = bytes {
                Ok(FloatType::F64(f64::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7]])))
            }
            else {
                Err("data not length enough".into())
            }
        }
        else {
            let bytes = data.read(4);
            if let Some(bytes) = bytes {
                Ok(FloatType::F32(f32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]])))
            }
            else {
                Err("data not length enough".into())
            }
        }
    }
    else {
        Err("no header data".into())
    }
}

impl XRType for f32 {
    fn serialize(&self) -> Result<Vec<u8>, crate::error::Error> {
        let bytes = self.to_le_bytes();
        Ok(vec![(Types::Float as u8), bytes[0], bytes[1], bytes[2], bytes[3]])
    }

    fn deserialize(data:&mut ByteCursor) -> Result<Self, crate::error::Error> {
        match deserialize_float(data) {
            Ok(v) => {
                match v {
                    FloatType::F32(v) => Ok(v),
                    FloatType::F64(v) => Ok(v as f32),
                }
            },
            Err(e) => Err(e),
        }
    }
}

impl XRType for f64 {
    fn serialize(&self) -> Result<Vec<u8>, crate::error::Error> {
        let bytes = self.to_le_bytes();
        Ok(vec![(Types::Float as u8) | 0x8, bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7]])
    }

    fn deserialize(data:&mut ByteCursor) -> Result<Self, crate::error::Error> {
        match deserialize_float(data) {
            Ok(v) => {
                match v {
                    FloatType::F32(v) => Ok(v as f64),
                    FloatType::F64(v) => Ok(v),
                }
            },
            Err(e) => Err(e),
        }
    }
}

pub struct SerNone(pub bool);//bool表示是否为Undefined

impl XRType for SerNone {
    fn serialize(&self) -> Result<Vec<u8>, crate::error::Error> {
        Ok(vec![(Types::None as u8) | (self.0 as u8) << 4])
    }

    fn deserialize(data:&mut ByteCursor) -> Result<Self, crate::error::Error> {
        if let Some(v) = data.read_one() {
            Ok(SerNone((v & 0x8) == 0x8))
        }
        else {
            Err("data length not enough".into())
        }
    }
}

impl XRType for String {
    fn serialize(&self) -> Result<Vec<u8>, crate::error::Error> {
        let bytes = self.as_bytes();
        let len = bytes.len();
        let mut result:Vec<u8> = serialize_usize(Types::String, len)?;
        for i in 0..len {
            result.push(bytes[i]);
        }
        Ok(result)
    }

    fn deserialize(data:&mut ByteCursor) -> Result<Self, crate::error::Error> {
        let bytesize = deserialize_usize(Types::String, data)?;
        let mut bytes:Vec<u8> = Vec::new();
        let next_datas = data.read(bytesize);
        if let Some(next_datas) = next_datas {
            bytes.extend_from_slice(next_datas);
        }
        else {
            return Err("data not length enough".into());
        }
        let result = String::from_utf8(bytes);
        match result {
            Ok(v) => Ok(v),
            Err(e) => Err(e.to_string().into()),
        }
    }
}

pub struct RefType(pub usize);

impl XRType for RefType {
    fn serialize(&self) -> Result<Vec<u8>, crate::error::Error> {
        serialize_usize(Types::Refence, self.0)
    }

    fn deserialize(data:&mut ByteCursor) -> Result<Self, crate::error::Error> where Self: Sized {
        let value = deserialize_usize(Types::Refence, data)?;
        Ok(Self(value))
    }
}

pub fn serialize_usize(t:Types, size:usize)->Result<Vec<u8>, crate::error::Error>{
    let data = size;
    if data <= 0xF {
        Ok(vec![(t as u8) | ((data as u8) << 4)])
    }
    else {
        let mut result:Vec<u8> = Vec::new();
        let mut head = (t as u8) | 0x8;
        let bitsize = 64 - data.leading_zeros();//这里不需要+1是因为usize是无符号数
        let bytesize = bitsize.div_ceil(8) as u8;
        //i128最多占用16个字节，所以bytesize的最大值也就是16所以4个bit完全足够
        head |= bytesize << 4;
        result.push(head);
        for i in 0..bytesize {
            result.push((data >> (i * 8)) as u8);
        }
        Ok(result)
    }
}

pub fn deserialize_usize(t:Types, data:&mut ByteCursor) -> Result<usize, crate::error::Error>{
    let head = data.read_one();
    if let Some(head) = head {
        if (head & (t as u8)) == 0 {
            return Err("type not match".into());
        }
        let len = head >> 4;
        if (head & 0x8) == 0 {
            return Ok(len as usize);
        }
        let mut value:usize = 0;
        for i in 0..len {
            let next_v = data.read_one();
            if let Some(next_v) = next_v {
                value |= (next_v.to_owned() as usize) << (i * 8);
            } else {
                return Err("data not length enough".into());
            }
        }
        Ok(value)
    }
    else {
        Err("no header data".into())
    }
}
